Skip to main content

Malware Detection


Memory forensics excels at detecting malware techniques that leave no artifacts on disk β€” injected code, process hollowing, rootkit hooks, and fileless payloads. These techniques should be run on any process of interest identified during process analysis.


Code Injection Detection​

malfind β€” Injected Code and PE Files​

Scans process VAD regions for memory-resident code that is suspicious based on three criteria: executable and writable protection (PAGE_EXECUTE_READWRITE), not backed by a file on disk, and containing PE headers or shellcode patterns. This is the primary plugin for detecting process injection and fileless malware.

# Scan all processes
vol.py -f <image> --profile=<profile> malfind

# Specific PID
vol.py -f <image> --profile=<profile> malfind -p <PID>

# Dump suspicious regions to files for further analysis
vol.py -f <image> --profile=<profile> malfind -p <PID> -D <output_dir>
Vol3 Equivalent
vol3 -f <image> windows.malfind
vol3 -f <image> windows.malfind --pid <PID>
vol3 -f <image> windows.malfind --dump
Analyzing malfind Output

Each hit shows the process, VAD start address, protection flags, and a hex/ASCII dump of the region. Look for:

  • MZ header at offset 0 β€” a PE file injected into process memory
  • Shellcode patterns (e.g., \x90\x90 NOP sleds, \xfc\xe8 common shellcode preambles)
  • False positives: JIT-compiled code from .NET/Java processes, packed executables β€” cross-reference with process reputation

Dump suspicious regions and submit to static analysis:

vol.py -f <image> --profile=<profile> malfind -D /cases/malfind_output/
# Run strings on each dump
strings -n 8 /cases/malfind_output/*.dmp | grep -iE "(http|cmd|powershell|registry|\\\\pipe)"

ldrmodules β€” Unlinked DLL Detection​

Compares three different in-memory lists of loaded modules (PEB InLoadOrderModuleList, PEB InMemoryOrderModuleList, and PEB InInitializationOrderModuleList) and the VAD tree. DLLs that appear in the VAD but are absent from the PEB lists are likely injected and hidden.

vol.py -f <image> --profile=<profile> ldrmodules -p <PID>

# Show only entries with discrepancies
vol.py -f <image> --profile=<profile> ldrmodules -p <PID> -v
Vol3 Equivalent

No direct equivalent in Vol3. Use windows.dlllist combined with windows.vadinfo and manually compare mapped regions against the DLL list.

What the Flags Mean

Each module is shown with three boolean columns: InLoad, InInit, InMem. A legitimately loaded DLL should be True in all three. A DLL showing False in any column β€” especially one with no mapped path β€” has been unlinked from the PEB, which is a common DLL injection concealment technique.


Process Hollowing Detection​

Process hollowing (a.k.a. RunPE) creates a legitimate process in suspended state, unmaps its memory, and replaces it with malicious code. Detection relies on cross-referencing multiple data sources:

Step 1 β€” Identify candidate processes:

# Look for processes with no PEB-listed executable path, or legitimate names with unusual paths
vol.py -f <image> --profile=<profile> ldrmodules | grep -v "True True True"

Step 2 β€” Check if the process executable on disk matches what is in memory:

# Dump the in-memory PE (procdump reconstructs from memory)
vol.py -f <image> --profile=<profile> procdump -p <PID> -D /cases/output/

# Hash and compare against known-good on-disk hash
sha256sum /cases/output/executable.<PID>.exe

Step 3 β€” Check VAD for anonymous executable regions (no mapped file):

vol.py -f <image> --profile=<profile> vadinfo -p <PID> | grep -A5 "EXECUTE"

A hollowed process typically has an anonymous EXECUTE_READWRITE VAD region at the base address where the original executable was mapped.

Vol3 Approach
vol3 -f <image> windows.vadinfo --pid <PID>
vol3 -f <image> windows.procdump --pid <PID>

Service and Driver Analysis​

svcscan β€” Windows Services​

Scans memory for SERVICE_RECORD structures, listing all registered Windows services including those hidden by rootkits. Useful for finding malicious services created for persistence.

vol.py -f <image> --profile=<profile> svcscan
Vol3 Equivalent
vol3 -f <image> windows.svcscan
What to Look For
  • Services with binary paths pointing to %TEMP%, %APPDATA%, or other non-standard locations
  • Services with generic or meaningless names
  • Services with no description
  • Services in RUNNING state associated with suspicious processes

modules β€” Loaded Kernel Modules​

Lists loaded kernel modules (drivers) by walking the PsLoadedModuleList. Like pslist for processes, this list can be manipulated by rootkits.

vol.py -f <image> --profile=<profile> modules
Vol3 Equivalent
vol3 -f <image> windows.modules

modscan β€” Kernel Module Pool Scan​

Scans raw memory for LDR_DATA_TABLE_ENTRY pool tags to find kernel modules, including those hidden from PsLoadedModuleList.

vol.py -f <image> --profile=<profile> modscan
Vol3 Equivalent
vol3 -f <image> windows.modscan
Compare modules vs modscan

As with pslist/psscan for processes, modules present in modscan but not modules have been unlinked β€” a kernel-level rootkit indicator.


driverirp β€” Driver IRP Hook Detection​

Examines the IRP (I/O Request Packet) dispatch table for each loaded driver and flags any entries pointing outside the driver's normal address range. Hooked IRP handlers redirect I/O operations through attacker-controlled code β€” a common rootkit technique for intercepting file, network, or keyboard I/O.

vol.py -f <image> --profile=<profile> driverirp -r <driver_name_regex>

# Example β€” check all drivers
vol.py -f <image> --profile=<profile> driverirp
Vol3 Equivalent
vol3 -f <image> windows.driverirp

ssdt β€” SSDT Hook Detection (Vol2 Only)​

Checks the System Service Descriptor Table (SSDT) for hooked entries. Rootkits hook the SSDT to intercept system calls and hide processes, files, or network connections. Entries pointing outside ntoskrnl.exe or win32k.sys address ranges are suspect.

vol.py -f <image> --profile=<profile> ssdt | grep -v "ntoskrnl\|win32k"
Vol3 Only

ssdt is a Vol2-only plugin. Vol3 does not have a direct equivalent β€” use windows.modules + windows.driverirp to identify suspicious kernel code.


apihooks β€” Userland API Hook Detection (Vol2 Only)​

Scans process memory for inline hooks and import address table (IAT) hooks in loaded modules. Hooks redirect API calls through attacker code before passing (or not passing) to the legitimate function.

vol.py -f <image> --profile=<profile> apihooks -p <PID>
Vol3 Only

apihooks is a Vol2-only plugin with no direct Vol3 equivalent.

Inline Hook Signatures

Common inline hook indicators: a JMP or CALL instruction at the very start of a function redirecting to an address outside the module's normal range. The apihooks output flags these automatically.


YARA Scanning​

Scan process memory or the full image with YARA rules β€” useful for detecting known malware families, shellcode patterns, or custom indicators.

# Vol2 β€” scan all process memory with a YARA rule file
vol.py -f <image> --profile=<profile> yarascan -y /rules/malware.yar

# Vol2 β€” scan specific PID
vol.py -f <image> --profile=<profile> yarascan -p <PID> -y /rules/malware.yar

# Vol2 β€” scan with inline YARA string
vol.py -f <image> --profile=<profile> yarascan -U "MZ\x90\x00"
Vol3 Equivalent
# Scan process VAD regions
vol3 -f <image> windows.vadyarascan --yara-file /rules/malware.yar

# Scan physical memory layers
vol3 -f <image> yarascan.YaraScan --yara-file /rules/malware.yar
Common Quick-Win YARA Patterns
# Find Mimikatz artifacts
vol.py -f <image> --profile=<profile> yarascan -U "sekurlsa"

# Find PowerShell encoded command artifacts
vol.py -f <image> --profile=<profile> yarascan -U "FromBase64String"

# Find common shellcode preamble
vol.py -f <image> --profile=<profile> yarascan -U "\xfc\xe8\x82\x00\x00\x00"

# Metasploit Meterpreter
vol.py -f <image> --profile=<profile> yarascan -U "metsrv"